home *** CD-ROM | disk | FTP | other *** search
/ Amiga Tools 5 / Amiga Tools 5.iso / tools / developer-tools / andere sprachen / perl5 / perl5.002 / mg.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-02-27  |  24.5 KB  |  1,373 lines

  1. /*    mg.c
  2.  *
  3.  *    Copyright (c) 1991-1994, Larry Wall
  4.  *
  5.  *    You may distribute under the terms of either the GNU General Public
  6.  *    License or the Artistic License, as specified in the README file.
  7.  *
  8.  */
  9.  
  10. /*
  11.  * "Sam sat on the ground and put his head in his hands.  'I wish I had never
  12.  * come here, and I don't want to see no more magic,' he said, and fell silent."
  13.  */
  14.  
  15. #include "EXTERN.h"
  16. #include "perl.h"
  17.  
  18. /* Omit -- it causes too much grief on mixed systems.
  19. #ifdef I_UNISTD
  20. # include <unistd.h>
  21. #endif
  22. */
  23.  
  24. /*
  25.  * Use the "DESTRUCTOR" scope cleanup to reinstate magic.
  26.  */
  27.  
  28. struct magic_state {
  29.     SV* mgs_sv;
  30.     U32 mgs_flags;
  31. };
  32. typedef struct magic_state MGS;
  33.  
  34. static void restore_magic _((void *p));
  35.  
  36. static MGS *
  37. save_magic(sv)
  38. SV* sv;
  39. {
  40.     MGS* mgs;
  41.  
  42.     assert(SvMAGICAL(sv));
  43.  
  44.     mgs = (MGS*)safemalloc(sizeof(MGS));
  45.     mgs->mgs_sv = sv;
  46.     mgs->mgs_flags = SvMAGICAL(sv) | SvREADONLY(sv);
  47.     SAVEDESTRUCTOR(restore_magic, mgs);
  48.  
  49.     SvMAGICAL_off(sv);
  50.     SvREADONLY_off(sv);
  51.     SvFLAGS(sv) |= (SvFLAGS(sv) & (SVp_IOK|SVp_NOK|SVp_POK)) >> PRIVSHIFT;
  52.  
  53.     return mgs;
  54. }
  55.  
  56. static void
  57. restore_magic(p)
  58. void* p;
  59. {
  60.     MGS *mgs = (MGS*)p;
  61.     SV* sv = mgs->mgs_sv;
  62.  
  63.     if (SvTYPE(sv) >= SVt_PVMG && SvMAGIC(sv))
  64.     {
  65.     if (mgs->mgs_flags)
  66.         SvFLAGS(sv) |= mgs->mgs_flags;
  67.     else
  68.         mg_magical(sv);
  69.     if (SvGMAGICAL(sv))
  70.         SvFLAGS(sv) &= ~(SVf_IOK|SVf_NOK|SVf_POK);
  71.     }
  72.  
  73.     Safefree(mgs);
  74. }
  75.  
  76.  
  77. void
  78. mg_magical(sv)
  79. SV* sv;
  80. {
  81.     MAGIC* mg;
  82.     for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
  83.     MGVTBL* vtbl = mg->mg_virtual;
  84.     if (vtbl) {
  85.         if (vtbl->svt_get && !(mg->mg_flags & MGf_GSKIP))
  86.         SvGMAGICAL_on(sv);
  87.         if (vtbl->svt_set)
  88.         SvSMAGICAL_on(sv);
  89.         if (!(SvFLAGS(sv) & (SVs_GMG|SVs_SMG)) || vtbl->svt_clear)
  90.         SvRMAGICAL_on(sv);
  91.     }
  92.     }
  93. }
  94.  
  95. int
  96. mg_get(sv)
  97. SV* sv;
  98. {
  99.     MGS* mgs;
  100.     MAGIC* mg;
  101.     MAGIC** mgp;
  102.  
  103.     ENTER;
  104.     mgs = save_magic(sv);
  105.  
  106.     mgp = &SvMAGIC(sv);
  107.     while ((mg = *mgp) != 0) {
  108.     MGVTBL* vtbl = mg->mg_virtual;
  109.     if (!(mg->mg_flags & MGf_GSKIP) && vtbl && vtbl->svt_get) {
  110.         (*vtbl->svt_get)(sv, mg);
  111.         /* Ignore this magic if it's been deleted */
  112.         if (*mgp == mg && (mg->mg_flags & MGf_GSKIP))
  113.         mgs->mgs_flags = 0;
  114.     }
  115.     /* Advance to next magic (complicated by possible deletion) */
  116.     if (*mgp == mg)
  117.         mgp = &mg->mg_moremagic;
  118.     }
  119.  
  120.     LEAVE;
  121.     return 0;
  122. }
  123.  
  124. int
  125. mg_set(sv)
  126. SV* sv;
  127. {
  128.     MGS* mgs;
  129.     MAGIC* mg;
  130.     MAGIC* nextmg;
  131.  
  132.     ENTER;
  133.     mgs = save_magic(sv);
  134.  
  135.     for (mg = SvMAGIC(sv); mg; mg = nextmg) {
  136.     MGVTBL* vtbl = mg->mg_virtual;
  137.     nextmg = mg->mg_moremagic;    /* it may delete itself */
  138.     if (mg->mg_flags & MGf_GSKIP) {
  139.         mg->mg_flags &= ~MGf_GSKIP;    /* setting requires another read */
  140.         mgs->mgs_flags = 0;
  141.     }
  142.     if (vtbl && vtbl->svt_set)
  143.         (*vtbl->svt_set)(sv, mg);
  144.     }
  145.  
  146.     LEAVE;
  147.     return 0;
  148. }
  149.  
  150. U32
  151. mg_len(sv)
  152. SV* sv;
  153. {
  154.     MAGIC* mg;
  155.     char *junk;
  156.     STRLEN len;
  157.  
  158.     for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
  159.     MGVTBL* vtbl = mg->mg_virtual;
  160.     if (vtbl && vtbl->svt_len) {
  161.         ENTER;
  162.         save_magic(sv);
  163.         /* omit MGf_GSKIP -- not changed here */
  164.         len = (*vtbl->svt_len)(sv, mg);
  165.         LEAVE;
  166.         return len;
  167.     }
  168.     }
  169.  
  170.     junk = SvPV(sv, len);
  171.     return len;
  172. }
  173.  
  174. int
  175. mg_clear(sv)
  176. SV* sv;
  177. {
  178.     MAGIC* mg;
  179.  
  180.     ENTER;
  181.     save_magic(sv);
  182.  
  183.     for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
  184.     MGVTBL* vtbl = mg->mg_virtual;
  185.     /* omit GSKIP -- never set here */
  186.     
  187.     if (vtbl && vtbl->svt_clear)
  188.         (*vtbl->svt_clear)(sv, mg);
  189.     }
  190.  
  191.     LEAVE;
  192.     return 0;
  193. }
  194.  
  195. MAGIC*
  196. mg_find(sv, type)
  197. SV* sv;
  198. int type;
  199. {
  200.     MAGIC* mg;
  201.     for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
  202.     if (mg->mg_type == type)
  203.         return mg;
  204.     }
  205.     return 0;
  206. }
  207.  
  208. int
  209. mg_copy(sv, nsv, key, klen)
  210. SV* sv;
  211. SV* nsv;
  212. char *key;
  213. STRLEN klen;
  214. {
  215.     int count = 0;
  216.     MAGIC* mg;
  217.     for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
  218.     if (isUPPER(mg->mg_type)) {
  219.         sv_magic(nsv, mg->mg_obj, toLOWER(mg->mg_type), key, klen);
  220.         count++;
  221.     }
  222.     }
  223.     return count;
  224. }
  225.  
  226. int
  227. mg_free(sv)
  228. SV* sv;
  229. {
  230.     MAGIC* mg;
  231.     MAGIC* moremagic;
  232.     for (mg = SvMAGIC(sv); mg; mg = moremagic) {
  233.     MGVTBL* vtbl = mg->mg_virtual;
  234.     moremagic = mg->mg_moremagic;
  235.     if (vtbl && vtbl->svt_free)
  236.         (*vtbl->svt_free)(sv, mg);
  237.     if (mg->mg_ptr && mg->mg_type != 'g')
  238.         Safefree(mg->mg_ptr);
  239.     if (mg->mg_flags & MGf_REFCOUNTED)
  240.         SvREFCNT_dec(mg->mg_obj);
  241.     Safefree(mg);
  242.     }
  243.     SvMAGIC(sv) = 0;
  244.     return 0;
  245. }
  246.  
  247. #if !defined(NSIG) || defined(M_UNIX) || defined(M_XENIX)
  248. #include <signal.h>
  249. #endif
  250.  
  251. U32
  252. magic_len(sv, mg)
  253. SV *sv;
  254. MAGIC *mg;
  255. {
  256.     register I32 paren;
  257.     register char *s;
  258.     register I32 i;
  259.     char *t;
  260.  
  261.     switch (*mg->mg_ptr) {
  262.     case '1': case '2': case '3': case '4':
  263.     case '5': case '6': case '7': case '8': case '9': case '&':
  264.     if (curpm) {
  265.         paren = atoi(mg->mg_ptr);
  266.       getparen:
  267.         if (curpm->op_pmregexp &&
  268.           paren <= curpm->op_pmregexp->nparens &&
  269.           (s = curpm->op_pmregexp->startp[paren]) &&
  270.           (t = curpm->op_pmregexp->endp[paren]) ) {
  271.         i = t - s;
  272.         if (i >= 0)
  273.             return i;
  274.         }
  275.     }
  276.     return 0;
  277.     break;
  278.     case '+':
  279.     if (curpm) {
  280.         paren = curpm->op_pmregexp->lastparen;
  281.         if (!paren)
  282.         return 0;
  283.         goto getparen;
  284.     }
  285.     return 0;
  286.     break;
  287.     case '`':
  288.     if (curpm) {
  289.         if (curpm->op_pmregexp &&
  290.           (s = curpm->op_pmregexp->subbeg) ) {
  291.         i = curpm->op_pmregexp->startp[0] - s;
  292.         if (i >= 0)
  293.             return i;
  294.         }
  295.     }
  296.     return 0;
  297.     case '\'':
  298.     if (curpm) {
  299.         if (curpm->op_pmregexp &&
  300.           (s = curpm->op_pmregexp->endp[0]) ) {
  301.         return (STRLEN) (curpm->op_pmregexp->subend - s);
  302.         }
  303.     }
  304.     return 0;
  305.     case ',':
  306.     return (STRLEN)ofslen;
  307.     case '\\':
  308.     return (STRLEN)orslen;
  309.     }
  310.     magic_get(sv,mg);
  311.     if (!SvPOK(sv) && SvNIOK(sv))
  312.     sv_2pv(sv, &na);
  313.     if (SvPOK(sv))
  314.     return SvCUR(sv);
  315.     return 0;
  316. }
  317.  
  318. int
  319. magic_get(sv, mg)
  320. SV *sv;
  321. MAGIC *mg;
  322. {
  323.     register I32 paren;
  324.     register char *s;
  325.     register I32 i;
  326.     char *t;
  327.  
  328.     switch (*mg->mg_ptr) {
  329.     case '\001':        /* ^A */
  330.     sv_setsv(sv, bodytarget);
  331.     break;
  332.     case '\004':        /* ^D */
  333.     sv_setiv(sv,(I32)(debug & 32767));
  334.     break;
  335.     case '\006':        /* ^F */
  336.     sv_setiv(sv,(I32)maxsysfd);
  337.     break;
  338.     case '\010':        /* ^H */
  339.     sv_setiv(sv,(I32)hints);
  340.     break;
  341.     case '\t':            /* ^I */
  342.     if (inplace)
  343.         sv_setpv(sv, inplace);
  344.     else
  345.         sv_setsv(sv,&sv_undef);
  346.     break;
  347.     case '\020':        /* ^P */
  348.     sv_setiv(sv,(I32)perldb);
  349.     break;
  350.     case '\024':        /* ^T */
  351.     sv_setiv(sv,(I32)basetime);
  352.     break;
  353.     case '\027':        /* ^W */
  354.     sv_setiv(sv,(I32)dowarn);
  355.     break;
  356.     case '1': case '2': case '3': case '4':
  357.     case '5': case '6': case '7': case '8': case '9': case '&':
  358.     if (curpm) {
  359.         paren = atoi(GvENAME(mg->mg_obj));
  360.       getparen:
  361.         if (curpm->op_pmregexp &&
  362.           paren <= curpm->op_pmregexp->nparens &&
  363.           (s = curpm->op_pmregexp->startp[paren]) &&
  364.           (t = curpm->op_pmregexp->endp[paren]) ) {
  365.         i = t - s;
  366.         if (i >= 0) {
  367.             MAGIC *tmg;
  368.             sv_setpvn(sv,s,i);
  369.             if (tainting && (tmg = mg_find(sv,'t')))
  370.             tmg->mg_len = 0;    /* guarantee $1 untainted */
  371.             break;
  372.         }
  373.         }
  374.     }
  375.     sv_setsv(sv,&sv_undef);
  376.     break;
  377.     case '+':
  378.     if (curpm) {
  379.         paren = curpm->op_pmregexp->lastparen;
  380.         if (paren)
  381.         goto getparen;
  382.     }
  383.     sv_setsv(sv,&sv_undef);
  384.     break;
  385.     case '`':
  386.     if (curpm) {
  387.         if (curpm->op_pmregexp &&
  388.           (s = curpm->op_pmregexp->subbeg) ) {
  389.         i = curpm->op_pmregexp->startp[0] - s;
  390.         if (i >= 0) {
  391.             sv_setpvn(sv,s,i);
  392.             break;
  393.         }
  394.         }
  395.     }
  396.     sv_setsv(sv,&sv_undef);
  397.     break;
  398.     case '\'':
  399.     if (curpm) {
  400.         if (curpm->op_pmregexp &&
  401.           (s = curpm->op_pmregexp->endp[0]) ) {
  402.         sv_setpvn(sv,s, curpm->op_pmregexp->subend - s);
  403.         break;
  404.         }
  405.     }
  406.     sv_setsv(sv,&sv_undef);
  407.     break;
  408.     case '.':
  409. #ifndef lint
  410.     if (GvIO(last_in_gv)) {
  411.         sv_setiv(sv,(I32)IoLINES(GvIO(last_in_gv)));
  412.     }
  413. #endif
  414.     break;
  415.     case '?':
  416.     sv_setiv(sv,(I32)statusvalue);
  417.     break;
  418.     case '^':
  419.     s = IoTOP_NAME(GvIOp(defoutgv));
  420.     if (s)
  421.         sv_setpv(sv,s);
  422.     else {
  423.         sv_setpv(sv,GvENAME(defoutgv));
  424.         sv_catpv(sv,"_TOP");
  425.     }
  426.     break;
  427.     case '~':
  428.     s = IoFMT_NAME(GvIOp(defoutgv));
  429.     if (!s)
  430.         s = GvENAME(defoutgv);
  431.     sv_setpv(sv,s);
  432.     break;
  433. #ifndef lint
  434.     case '=':
  435.     sv_setiv(sv,(I32)IoPAGE_LEN(GvIOp(defoutgv)));
  436.     break;
  437.     case '-':
  438.     sv_setiv(sv,(I32)IoLINES_LEFT(GvIOp(defoutgv)));
  439.     break;
  440.     case '%':
  441.     sv_setiv(sv,(I32)IoPAGE(GvIOp(defoutgv)));
  442.     break;
  443. #endif
  444.     case ':':
  445.     break;
  446.     case '/':
  447.     break;
  448.     case '[':
  449.     sv_setiv(sv,(I32)curcop->cop_arybase);
  450.     break;
  451.     case '|':
  452.     sv_setiv(sv, (IoFLAGS(GvIOp(defoutgv)) & IOf_FLUSH) != 0 );
  453.     break;
  454.     case ',':
  455.     sv_setpvn(sv,ofs,ofslen);
  456.     break;
  457.     case '\\':
  458.     sv_setpvn(sv,ors,orslen);
  459.     break;
  460.     case '#':
  461.     sv_setpv(sv,ofmt);
  462.     break;
  463.     case '!':
  464. #ifdef VMS
  465.     sv_setnv(sv,(double)((errno == EVMSERR) ? vaxc$errno : errno));
  466. #else
  467.     sv_setnv(sv,(double)errno);
  468. #endif
  469.     sv_setpv(sv, errno ? Strerror(errno) : "");
  470.     SvNOK_on(sv);    /* what a wonderful hack! */
  471.     break;
  472.     case '<':
  473.     sv_setiv(sv,(I32)uid);
  474.     break;
  475.     case '>':
  476.     sv_setiv(sv,(I32)euid);
  477.     break;
  478.     case '(':
  479.     s = buf;
  480.     (void)sprintf(s,"%d",(int)gid);
  481.     goto add_groups;
  482.     case ')':
  483.     s = buf;
  484.     (void)sprintf(s,"%d",(int)egid);
  485.       add_groups:
  486.     while (*s) s++;
  487. #ifdef HAS_GETGROUPS
  488. #ifndef NGROUPS
  489. #define NGROUPS 32
  490. #endif
  491.     {
  492.         Groups_t gary[NGROUPS];
  493.  
  494.         i = getgroups(NGROUPS,gary);
  495.         while (--i >= 0) {
  496.         (void)sprintf(s," %ld", (long)gary[i]);
  497.         while (*s) s++;
  498.         }
  499.     }
  500. #endif
  501.     sv_setpv(sv,buf);
  502.     break;
  503.     case '*':
  504.     break;
  505.     case '0':
  506.     break;
  507.     }
  508.     return 0;
  509. }
  510.  
  511. int
  512. magic_getuvar(sv, mg)
  513. SV *sv;
  514. MAGIC *mg;
  515. {
  516.     struct ufuncs *uf = (struct ufuncs *)mg->mg_ptr;
  517.  
  518.     if (uf && uf->uf_val)
  519.     (*uf->uf_val)(uf->uf_index, sv);
  520.     return 0;
  521. }
  522.  
  523. int
  524. magic_setenv(sv,mg)
  525. SV* sv;
  526. MAGIC* mg;
  527. {
  528.     register char *s;
  529.     STRLEN len;
  530.     I32 i;
  531.     s = SvPV(sv,len);
  532.     my_setenv(mg->mg_ptr,s);
  533. #ifdef DYNAMIC_ENV_FETCH
  534.      /* We just undefd an environment var.  Is a replacement */
  535.      /* waiting in the wings? */
  536.     if (!len) {
  537.     SV **envsvp;
  538.     if (envsvp = hv_fetch(GvHVn(envgv),mg->mg_ptr,mg->mg_len,FALSE))
  539.         s = SvPV(*envsvp,len);
  540.     }
  541. #endif
  542.                 /* And you'll never guess what the dog had */
  543.                 /*   in its mouth... */
  544.     if (tainting) {
  545.     if (s && strEQ(mg->mg_ptr,"PATH")) {
  546.         char *strend = s + len;
  547.  
  548.         while (s < strend) {
  549.         s = cpytill(tokenbuf,s,strend,':',&i);
  550.         s++;
  551.         if (*tokenbuf != '/'
  552.           || (Stat(tokenbuf,&statbuf) && (statbuf.st_mode & 2)) )
  553.             MgTAINTEDDIR_on(mg);
  554.         }
  555.     }
  556.     }
  557.     return 0;
  558. }
  559.  
  560. int
  561. magic_clearenv(sv,mg)
  562. SV* sv;
  563. MAGIC* mg;
  564. {
  565.     my_setenv(mg->mg_ptr,Nullch);
  566.     return 0;
  567. }
  568.  
  569. #ifdef HAS_SIGACTION
  570. /* set up reliable signal() clone */
  571.  
  572. typedef void (*Sigfunc) _((int));
  573.  
  574. static
  575. Sigfunc rsignal(signo,handler)
  576. int signo;
  577. Sigfunc handler;
  578. {
  579.     struct sigaction act,oact;
  580.     
  581.     act.sa_handler = handler;
  582.     sigemptyset(&act.sa_mask);
  583.     act.sa_flags = 0;
  584. #ifdef SIGALRM    
  585.     if (signo == SIGALRM) {
  586. #else
  587.     if (0) {
  588. #endif        
  589. #ifdef SA_INTERRUPT
  590.     act.sa_flags |= SA_INTERRUPT;    /* SunOS */
  591. #endif    
  592.     } else {
  593. #ifdef SA_RESTART
  594.     act.sa_flags |= SA_RESTART;    /* SVR4, 4.3+BSD */
  595. #endif
  596.     }
  597.     if (sigaction(signo, &act, &oact) < 0)
  598.         return(SIG_ERR);
  599.     else
  600.         return(oact.sa_handler);
  601. }
  602.  
  603. #else
  604.  
  605. /* ah well, so much for reliability */
  606.  
  607. #define rsignal(x,y) signal(x,y)
  608.  
  609. #endif
  610.  
  611.  
  612. int
  613. magic_setsig(sv,mg)
  614. SV* sv;
  615. MAGIC* mg;
  616. {
  617.     register char *s;
  618.     I32 i;
  619.     SV** svp;
  620.  
  621.     s = mg->mg_ptr;
  622.     if (*s == '_') {
  623.     if (strEQ(s,"__DIE__"))
  624.         svp = &diehook;
  625.     else if (strEQ(s,"__WARN__"))
  626.         svp = &warnhook;
  627.     else if (strEQ(s,"__PARSE__"))
  628.         svp = &parsehook;
  629.     else
  630.         croak("No such hook: %s", s);
  631.     i = 0;
  632.     if (*svp) {
  633.         SvREFCNT_dec(*svp);
  634.         *svp = 0;
  635.     }
  636.     }
  637.     else {
  638.     i = whichsig(s);    /* ...no, a brick */
  639.     if (!i) {
  640.         if (dowarn || strEQ(s,"ALARM"))
  641.         warn("No such signal: SIG%s", s);
  642.         return 0;
  643.     }
  644.     }
  645.     if (SvTYPE(sv) == SVt_PVGV || SvROK(sv)) {
  646.     if (i)
  647.         (void)rsignal(i,sighandler);
  648.     else
  649.         *svp = SvREFCNT_inc(sv);
  650.     return 0;
  651.     }
  652.     s = SvPV_force(sv,na);
  653.     if (strEQ(s,"IGNORE")) {
  654.     if (i)
  655.         (void)rsignal(i,SIG_IGN);
  656.     else
  657.         *svp = 0;
  658.     }
  659.     else if (strEQ(s,"DEFAULT") || !*s) {
  660.     if (i)
  661.         (void)rsignal(i,SIG_DFL);
  662.     else
  663.         *svp = 0;
  664.     }
  665.     else {
  666.     if (!strchr(s,':') && !strchr(s,'\'')) {
  667.         sprintf(tokenbuf, "main::%s",s);
  668.         sv_setpv(sv,tokenbuf);
  669.     }
  670.     if (i)
  671.         (void)rsignal(i,sighandler);
  672.     else
  673.         *svp = SvREFCNT_inc(sv);
  674.     }
  675.     return 0;
  676. }
  677.  
  678. int
  679. magic_setisa(sv,mg)
  680. SV* sv;
  681. MAGIC* mg;
  682. {
  683.     sub_generation++;
  684.     return 0;
  685. }
  686.  
  687. #ifdef OVERLOAD
  688.  
  689. int
  690. magic_setamagic(sv,mg)
  691. SV* sv;
  692. MAGIC* mg;
  693. {
  694.     /* HV_badAMAGIC_on(Sv_STASH(sv)); */
  695.     amagic_generation++;
  696.  
  697.     return 0;
  698. }
  699. #endif /* OVERLOAD */
  700.  
  701. static int
  702. magic_methpack(sv,mg,meth)
  703. SV* sv;
  704. MAGIC* mg;
  705. char *meth;
  706. {
  707.     dSP;
  708.  
  709.     ENTER;
  710.     SAVETMPS;
  711.     PUSHMARK(sp);
  712.     EXTEND(sp, 2);
  713.     PUSHs(mg->mg_obj);
  714.     if (mg->mg_ptr)
  715.     PUSHs(sv_2mortal(newSVpv(mg->mg_ptr, mg->mg_len)));
  716.     else if (mg->mg_type == 'p')
  717.     PUSHs(sv_2mortal(newSViv(mg->mg_len)));
  718.     PUTBACK;
  719.  
  720.     if (perl_call_method(meth, G_SCALAR))
  721.     sv_setsv(sv, *stack_sp--);
  722.  
  723.     FREETMPS;
  724.     LEAVE;
  725.     return 0;
  726. }
  727.  
  728. int
  729. magic_getpack(sv,mg)
  730. SV* sv;
  731. MAGIC* mg;
  732. {
  733.     magic_methpack(sv,mg,"FETCH");
  734.     if (mg->mg_ptr)
  735.     mg->mg_flags |= MGf_GSKIP;
  736.     return 0;
  737. }
  738.  
  739. int
  740. magic_setpack(sv,mg)
  741. SV* sv;
  742. MAGIC* mg;
  743. {
  744.     dSP;
  745.  
  746.     PUSHMARK(sp);
  747.     EXTEND(sp, 3);
  748.     PUSHs(mg->mg_obj);
  749.     if (mg->mg_ptr)
  750.     PUSHs(sv_2mortal(newSVpv(mg->mg_ptr, mg->mg_len)));
  751.     else if (mg->mg_type == 'p')
  752.     PUSHs(sv_2mortal(newSViv(mg->mg_len)));
  753.     PUSHs(sv);
  754.     PUTBACK;
  755.  
  756.     perl_call_method("STORE", G_SCALAR|G_DISCARD);
  757.  
  758.     return 0;
  759. }
  760.  
  761. int
  762. magic_clearpack(sv,mg)
  763. SV* sv;
  764. MAGIC* mg;
  765. {
  766.     return magic_methpack(sv,mg,"DELETE");
  767. }
  768.  
  769. int magic_wipepack(sv,mg)
  770. SV* sv;
  771. MAGIC* mg;
  772. {
  773.     dSP;
  774.  
  775.     PUSHMARK(sp);
  776.     XPUSHs(mg->mg_obj);
  777.     PUTBACK;
  778.  
  779.     perl_call_method("CLEAR", G_SCALAR|G_DISCARD);
  780.  
  781.     return 0;
  782. }
  783.  
  784. int
  785. magic_nextpack(sv,mg,key)
  786. SV* sv;
  787. MAGIC* mg;
  788. SV* key;
  789. {
  790.     dSP;
  791.     char *meth = SvOK(key) ? "NEXTKEY" : "FIRSTKEY";
  792.  
  793.     ENTER;
  794.     SAVETMPS;
  795.     PUSHMARK(sp);
  796.     EXTEND(sp, 2);
  797.     PUSHs(mg->mg_obj);
  798.     if (SvOK(key))
  799.     PUSHs(key);
  800.     PUTBACK;
  801.  
  802.     if (perl_call_method(meth, G_SCALAR))
  803.     sv_setsv(key, *stack_sp--);
  804.  
  805.     FREETMPS;
  806.     LEAVE;
  807.     return 0;
  808. }
  809.  
  810. int
  811. magic_existspack(sv,mg)
  812. SV* sv;
  813. MAGIC* mg;
  814. {
  815.     return magic_methpack(sv,mg,"EXISTS");
  816.  
  817. int
  818. magic_setdbline(sv,mg)
  819. SV* sv;
  820. MAGIC* mg;
  821. {
  822.     OP *o;
  823.     I32 i;
  824.     GV* gv;
  825.     SV** svp;
  826.  
  827.     gv = DBline;
  828.     i = SvTRUE(sv);
  829.     svp = av_fetch(GvAV(gv),atoi(mg->mg_ptr), FALSE);
  830.     if (svp && SvIOKp(*svp) && (o = (OP*)SvSTASH(*svp)))
  831.     o->op_private = i;
  832.     else
  833.     warn("Can't break at that line\n");
  834.     return 0;
  835. }
  836.  
  837. int
  838. magic_getarylen(sv,mg)
  839. SV* sv;
  840. MAGIC* mg;
  841. {
  842.     sv_setiv(sv, AvFILL((AV*)mg->mg_obj) + curcop->cop_arybase);
  843.     return 0;
  844. }
  845.  
  846. int
  847. magic_setarylen(sv,mg)
  848. SV* sv;
  849. MAGIC* mg;
  850. {
  851.     av_fill((AV*)mg->mg_obj, SvIV(sv) - curcop->cop_arybase);
  852.     return 0;
  853. }
  854.  
  855. int
  856. magic_getpos(sv,mg)
  857. SV* sv;
  858. MAGIC* mg;
  859. {
  860.     SV* lsv = LvTARG(sv);
  861.     
  862.     if (SvTYPE(lsv) >= SVt_PVMG && SvMAGIC(lsv)) {
  863.     mg = mg_find(lsv, 'g');
  864.     if (mg && mg->mg_len >= 0) {
  865.         sv_setiv(sv, mg->mg_len + curcop->cop_arybase);
  866.         return 0;
  867.     }
  868.     }
  869.     (void)SvOK_off(sv);
  870.     return 0;
  871. }
  872.  
  873. int
  874. magic_setpos(sv,mg)
  875. SV* sv;
  876. MAGIC* mg;
  877. {
  878.     SV* lsv = LvTARG(sv);
  879.     SSize_t pos;
  880.     STRLEN len;
  881.  
  882.     mg = 0;
  883.     
  884.     if (SvTYPE(lsv) >= SVt_PVMG && SvMAGIC(lsv))
  885.     mg = mg_find(lsv, 'g');
  886.     if (!mg) {
  887.     if (!SvOK(sv))
  888.         return 0;
  889.     sv_magic(lsv, (SV*)0, 'g', Nullch, 0);
  890.     mg = mg_find(lsv, 'g');
  891.     }
  892.     else if (!SvOK(sv)) {
  893.     mg->mg_len = -1;
  894.     return 0;
  895.     }
  896.     len = SvPOK(lsv) ? SvCUR(lsv) : sv_len(lsv);
  897.  
  898.     pos = SvIV(sv) - curcop->cop_arybase;
  899.     if (pos < 0) {
  900.     pos += len;
  901.     if (pos < 0)
  902.         pos = 0;
  903.     }
  904.     else if (pos > len)
  905.     pos = len;
  906.     mg->mg_len = pos;
  907.  
  908.     return 0;
  909. }
  910.  
  911. int
  912. magic_getglob(sv,mg)
  913. SV* sv;
  914. MAGIC* mg;
  915. {
  916.     gv_efullname(sv,((GV*)sv));/* a gv value, be nice */
  917.     return 0;
  918. }
  919.  
  920. int
  921. magic_setglob(sv,mg)
  922. SV* sv;
  923. MAGIC* mg;
  924. {
  925.     register char *s;
  926.     GV* gv;
  927.  
  928.     if (!SvOK(sv))
  929.     return 0;
  930.     s = SvPV(sv, na);
  931.     if (*s == '*' && s[1])
  932.     s++;
  933.     gv = gv_fetchpv(s,TRUE, SVt_PVGV);
  934.     if (sv == (SV*)gv)
  935.     return 0;
  936.     if (GvGP(sv))
  937.     gp_free(sv);
  938.     GvGP(sv) = gp_ref(GvGP(gv));
  939.     if (!GvAV(gv))
  940.     gv_AVadd(gv);
  941.     if (!GvHV(gv))
  942.     gv_HVadd(gv);
  943.     if (!GvIOp(gv))
  944.     GvIOp(gv) = newIO();
  945.     return 0;
  946. }
  947.  
  948. int
  949. magic_setsubstr(sv,mg)
  950. SV* sv;
  951. MAGIC* mg;
  952. {
  953.     STRLEN len;
  954.     char *tmps = SvPV(sv,len);
  955.     sv_insert(LvTARG(sv),LvTARGOFF(sv),LvTARGLEN(sv), tmps, len);
  956.     return 0;
  957. }
  958.  
  959. int
  960. magic_gettaint(sv,mg)
  961. SV* sv;
  962. MAGIC* mg;
  963. {
  964.     if (mg->mg_len & 1)
  965.     tainted = TRUE;
  966.     else if (mg->mg_len & 2 && mg->mg_obj == sv)    /* kludge */
  967.     tainted = TRUE;
  968.     return 0;
  969. }
  970.  
  971. int
  972. magic_settaint(sv,mg)
  973. SV* sv;
  974. MAGIC* mg;
  975. {
  976.     if (localizing) {
  977.     if (localizing == 1)
  978.         mg->mg_len <<= 1;
  979.     else
  980.         mg->mg_len >>= 1;
  981.     }
  982.     else if (tainted)
  983.     mg->mg_len |= 1;
  984.     else
  985.     mg->mg_len &= ~1;
  986.     return 0;
  987. }
  988.  
  989. int
  990. magic_setvec(sv,mg)
  991. SV* sv;
  992. MAGIC* mg;
  993. {
  994.     do_vecset(sv);    /* XXX slurp this routine */
  995.     return 0;
  996. }
  997.  
  998. int
  999. magic_setmglob(sv,mg)
  1000. SV* sv;
  1001. MAGIC* mg;
  1002. {
  1003.     mg->mg_len = -1;
  1004.     SvSCREAM_off(sv);
  1005.     return 0;
  1006. }
  1007.  
  1008. int
  1009. magic_setbm(sv,mg)
  1010. SV* sv;
  1011. MAGIC* mg;
  1012. {
  1013.     sv_unmagic(sv, 'B');
  1014.     SvVALID_off(sv);
  1015.     return 0;
  1016. }
  1017.  
  1018. int
  1019. magic_setuvar(sv,mg)
  1020. SV* sv;
  1021. MAGIC* mg;
  1022. {
  1023.     struct ufuncs *uf = (struct ufuncs *)mg->mg_ptr;
  1024.  
  1025.     if (uf && uf->uf_set)
  1026.     (*uf->uf_set)(uf->uf_index, sv);
  1027.     return 0;
  1028. }
  1029.  
  1030. int
  1031. magic_set(sv,mg)
  1032. SV* sv;
  1033. MAGIC* mg;
  1034. {
  1035.     register char *s;
  1036.     I32 i;
  1037.     STRLEN len;
  1038.     switch (*mg->mg_ptr) {
  1039.     case '\001':    /* ^A */
  1040.     sv_setsv(bodytarget, sv);
  1041.     break;
  1042.     case '\004':    /* ^D */
  1043.     debug = (SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)) | 0x80000000;
  1044.     DEBUG_x(dump_all());
  1045.     break;
  1046.     case '\006':    /* ^F */
  1047.     maxsysfd = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
  1048.     break;
  1049.     case '\010':    /* ^H */
  1050.     hints = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
  1051.     break;
  1052.     case '\t':    /* ^I */
  1053.     if (inplace)
  1054.         Safefree(inplace);
  1055.     if (SvOK(sv))
  1056.         inplace = savepv(SvPV(sv,na));
  1057.     else
  1058.         inplace = Nullch;
  1059.     break;
  1060.     case '\020':    /* ^P */
  1061.     i = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
  1062.     if (i != perldb) {
  1063.         if (perldb)
  1064.         oldlastpm = curpm;
  1065.         else
  1066.         curpm = oldlastpm;
  1067.     }
  1068.     perldb = i;
  1069.     break;
  1070.     case '\024':    /* ^T */
  1071.     basetime = (Time_t)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
  1072.     break;
  1073.     case '\027':    /* ^W */
  1074.     dowarn = (bool)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
  1075.     break;
  1076.     case '.':
  1077.     if (localizing) {
  1078.         if (localizing == 1)
  1079.         save_sptr((SV**)&last_in_gv);
  1080.     }
  1081.     else if (SvOK(sv))
  1082.         IoLINES(GvIOp(last_in_gv)) = (long)SvIV(sv);
  1083.     break;
  1084.     case '^':
  1085.     Safefree(IoTOP_NAME(GvIOp(defoutgv)));
  1086.     IoTOP_NAME(GvIOp(defoutgv)) = s = savepv(SvPV(sv,na));
  1087.     IoTOP_GV(GvIOp(defoutgv)) = gv_fetchpv(s,TRUE, SVt_PVIO);
  1088.     break;
  1089.     case '~':
  1090.     Safefree(IoFMT_NAME(GvIOp(defoutgv)));
  1091.     IoFMT_NAME(GvIOp(defoutgv)) = s = savepv(SvPV(sv,na));
  1092.     IoFMT_GV(GvIOp(defoutgv)) = gv_fetchpv(s,TRUE, SVt_PVIO);
  1093.     break;
  1094.     case '=':
  1095.     IoPAGE_LEN(GvIOp(defoutgv)) = (long)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
  1096.     break;
  1097.     case '-':
  1098.     IoLINES_LEFT(GvIOp(defoutgv)) = (long)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
  1099.     if (IoLINES_LEFT(GvIOp(defoutgv)) < 0L)
  1100.         IoLINES_LEFT(GvIOp(defoutgv)) = 0L;
  1101.     break;
  1102.     case '%':
  1103.     IoPAGE(GvIOp(defoutgv)) = (long)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
  1104.     break;
  1105.     case '|':
  1106.     IoFLAGS(GvIOp(defoutgv)) &= ~IOf_FLUSH;
  1107.     if ((SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)) != 0) {
  1108.         IoFLAGS(GvIOp(defoutgv)) |= IOf_FLUSH;
  1109.     }
  1110.     break;
  1111.     case '*':
  1112.     i = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
  1113.     multiline = (i != 0);
  1114.     break;
  1115.     case '/':
  1116.     SvREFCNT_dec(nrs);
  1117.     nrs = newSVsv(sv);
  1118.     SvREFCNT_dec(rs);
  1119.     rs = SvREFCNT_inc(nrs);
  1120.     break;
  1121.     case '\\':
  1122.     if (ors)
  1123.         Safefree(ors);
  1124.     ors = savepv(SvPV(sv,orslen));
  1125.     break;
  1126.     case ',':
  1127.     if (ofs)
  1128.         Safefree(ofs);
  1129.     ofs = savepv(SvPV(sv, ofslen));
  1130.     break;
  1131.     case '#':
  1132.     if (ofmt)
  1133.         Safefree(ofmt);
  1134.     ofmt = savepv(SvPV(sv,na));
  1135.     break;
  1136.     case '[':
  1137.     compiling.cop_arybase = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
  1138.     break;
  1139.     case '?':
  1140.     statusvalue = FIXSTATUS(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
  1141.     break;
  1142.     case '!':
  1143.     SETERRNO(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv),4);        /* will anyone ever use this? */
  1144.     break;
  1145.     case '<':
  1146.     uid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
  1147.     if (delaymagic) {
  1148.         delaymagic |= DM_RUID;
  1149.         break;                /* don't do magic till later */
  1150.     }
  1151. #ifdef HAS_SETRUID
  1152.     (void)setruid((Uid_t)uid);
  1153. #else
  1154. #ifdef HAS_SETREUID
  1155.     (void)setreuid((Uid_t)uid, (Uid_t)-1);
  1156. #else
  1157. #ifdef HAS_SETRESUID
  1158.       (void)setresuid((Uid_t)uid, (Uid_t)-1, (Uid_t)-1);
  1159. #else
  1160.     if (uid == euid)        /* special case $< = $> */
  1161.         (void)setuid(uid);
  1162.     else {
  1163.         uid = (I32)getuid();
  1164.         croak("setruid() not implemented");
  1165.     }
  1166. #endif
  1167. #endif
  1168. #endif
  1169.     uid = (I32)getuid();
  1170.     tainting |= (uid && (euid != uid || egid != gid));
  1171.     break;
  1172.     case '>':
  1173.     euid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
  1174.     if (delaymagic) {
  1175.         delaymagic |= DM_EUID;
  1176.         break;                /* don't do magic till later */
  1177.     }
  1178. #ifdef HAS_SETEUID
  1179.     (void)seteuid((Uid_t)euid);
  1180. #else
  1181. #ifdef HAS_SETREUID
  1182.     (void)setreuid((Uid_t)-1, (Uid_t)euid);
  1183. #else
  1184. #ifdef HAS_SETRESUID
  1185.     (void)setresuid((Uid_t)-1, (Uid_t)euid, (Uid_t)-1);
  1186. #else
  1187.     if (euid == uid)        /* special case $> = $< */
  1188.         setuid(euid);
  1189.     else {
  1190.         euid = (I32)geteuid();
  1191.         croak("seteuid() not implemented");
  1192.     }
  1193. #endif
  1194. #endif
  1195. #endif
  1196.     euid = (I32)geteuid();
  1197.     tainting |= (uid && (euid != uid || egid != gid));
  1198.     break;
  1199.     case '(':
  1200.     gid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
  1201.     if (delaymagic) {
  1202.         delaymagic |= DM_RGID;
  1203.         break;                /* don't do magic till later */
  1204.     }
  1205. #ifdef HAS_SETRGID
  1206.     (void)setrgid((Gid_t)gid);
  1207. #else
  1208. #ifdef HAS_SETREGID
  1209.     (void)setregid((Gid_t)gid, (Gid_t)-1);
  1210. #else
  1211. #ifdef HAS_SETRESGID
  1212.       (void)setresgid((Gid_t)gid, (Gid_t)-1, (Gid_t) 1);
  1213. #else
  1214.     if (gid == egid)            /* special case $( = $) */
  1215.         (void)setgid(gid);
  1216.     else {
  1217.         gid = (I32)getgid();
  1218.         croak("setrgid() not implemented");
  1219.     }
  1220. #endif
  1221. #endif
  1222. #endif
  1223.     gid = (I32)getgid();
  1224.     tainting |= (uid && (euid != uid || egid != gid));
  1225.     break;
  1226.     case ')':
  1227.     egid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
  1228.     if (delaymagic) {
  1229.         delaymagic |= DM_EGID;
  1230.         break;                /* don't do magic till later */
  1231.     }
  1232. #ifdef HAS_SETEGID
  1233.     (void)setegid((Gid_t)egid);
  1234. #else
  1235. #ifdef HAS_SETREGID
  1236.     (void)setregid((Gid_t)-1, (Gid_t)egid);
  1237. #else
  1238. #ifdef HAS_SETRESGID
  1239.     (void)setresgid((Gid_t)-1, (Gid_t)egid, (Gid_t)-1);
  1240. #else
  1241.     if (egid == gid)            /* special case $) = $( */
  1242.         (void)setgid(egid);
  1243.     else {
  1244.         egid = (I32)getegid();
  1245.         croak("setegid() not implemented");
  1246.     }
  1247. #endif
  1248. #endif
  1249. #endif
  1250.     egid = (I32)getegid();
  1251.     tainting |= (uid && (euid != uid || egid != gid));
  1252.     break;
  1253.     case ':':
  1254.     chopset = SvPV_force(sv,na);
  1255.     break;
  1256.     case '0':
  1257.     if (!origalen) {
  1258.         s = origargv[0];
  1259.         s += strlen(s);
  1260.         /* See if all the arguments are contiguous in memory */
  1261.         for (i = 1; i < origargc; i++) {
  1262.         if (origargv[i] == s + 1)
  1263.             s += strlen(++s);    /* this one is ok too */
  1264.         }
  1265.         if (origenviron[0] == s + 1) {    /* can grab env area too? */
  1266.         my_setenv("NoNeSuCh", Nullch);
  1267.                         /* force copy of environment */
  1268.         for (i = 0; origenviron[i]; i++)
  1269.             if (origenviron[i] == s + 1)
  1270.             s += strlen(++s);
  1271.         }
  1272.         origalen = s - origargv[0];
  1273.     }
  1274.     s = SvPV_force(sv,len);
  1275.     i = len;
  1276.     if (i >= origalen) {
  1277.         i = origalen;
  1278.         SvCUR_set(sv, i);
  1279.         *SvEND(sv) = '\0';
  1280.         Copy(s, origargv[0], i, char);
  1281.     }
  1282.     else {
  1283.         Copy(s, origargv[0], i, char);
  1284.         s = origargv[0]+i;
  1285.         *s++ = '\0';
  1286.         while (++i < origalen)
  1287.         *s++ = ' ';
  1288.         s = origargv[0]+i;
  1289.         for (i = 1; i < origargc; i++)
  1290.         origargv[i] = Nullch;
  1291.     }
  1292.     break;
  1293.     }
  1294.     return 0;
  1295. }
  1296.  
  1297. I32
  1298. whichsig(sig)
  1299. char *sig;
  1300. {
  1301.     register char **sigv;
  1302.  
  1303.     for (sigv = sig_name+1; *sigv; sigv++)
  1304.     if (strEQ(sig,*sigv))
  1305.         return sig_num[sigv - sig_name];
  1306. #ifdef SIGCLD
  1307.     if (strEQ(sig,"CHLD"))
  1308.     return SIGCLD;
  1309. #endif
  1310. #ifdef SIGCHLD
  1311.     if (strEQ(sig,"CLD"))
  1312.     return SIGCHLD;
  1313. #endif
  1314.     return 0;
  1315. }
  1316.  
  1317. Signal_t
  1318. sighandler(sig)
  1319. int sig;
  1320. {
  1321.     dSP;
  1322.     GV *gv;
  1323.     HV *st;
  1324.     SV *sv;
  1325.     CV *cv;
  1326.     AV *oldstack;
  1327.     char *signame; 
  1328.  
  1329. #ifdef OS2        /* or anybody else who requires SIG_ACK */
  1330.     signal(sig, SIG_ACK);
  1331. #endif
  1332.  
  1333.     signame = sig_name[sig];
  1334.     cv = sv_2cv(*hv_fetch(GvHVn(siggv),signame,strlen(signame),
  1335.               TRUE),
  1336.         &st, &gv, TRUE);
  1337.     if (!cv || !CvROOT(cv) &&
  1338.     *signame == 'C' && instr(signame,"LD")) {
  1339.     
  1340.     if (signame[1] == 'H')
  1341.         cv = sv_2cv(*hv_fetch(GvHVn(siggv),"CLD",3,TRUE),
  1342.             &st, &gv, TRUE);
  1343.     else
  1344.         cv = sv_2cv(*hv_fetch(GvHVn(siggv),"CHLD",4,TRUE),
  1345.             &st, &gv, TRUE);
  1346.     /* gag */
  1347.     }
  1348.     if (!cv || !CvROOT(cv)) {
  1349.     if (dowarn)
  1350.         warn("SIG%s handler \"%s\" not defined.\n",
  1351.         signame, GvENAME(gv) );
  1352.     return;
  1353.     }
  1354.  
  1355.     oldstack = stack;
  1356.     if (stack != signalstack)
  1357.     AvFILL(signalstack) = 0;
  1358.     SWITCHSTACK(stack, signalstack);
  1359.  
  1360.     sv = sv_newmortal();
  1361.     sv_setpv(sv,signame);
  1362.     PUSHMARK(sp);
  1363.     PUSHs(sv);
  1364.     PUTBACK;
  1365.  
  1366.     perl_call_sv((SV*)cv, G_DISCARD);
  1367.  
  1368.     SWITCHSTACK(signalstack, oldstack);
  1369.  
  1370.     return;
  1371. }
  1372.